[小ネタ] Windows Server 2022 EC2にWindows Terminalをインストールする (ついでにwingetも)

[小ネタ] Windows Server 2022 EC2にWindows Terminalをインストールする (ついでにwingetも)

Clock Icon2021.09.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

小ネタです。

先月リリースされたWindows Server 2022はOSのビルドバージョンとしては10.0.20348でありWindows Terminalがインストール可能なビルドとなります。

というわけで誰もがWindows Server 2022にWindows Terminalをインストールしようと考えるに決まっており既に先駆者もいるわけです。
たとえば以下は元MVPで現Microsoft社員のThomas MaurerさんのブログでWindows Server 2022プレビュー時点から既に試されています。

https://www.thomasmaurer.ch/2021/05/install-windows-terminal-on-windows-server-2022/

まあ、OSのビルドバージョンさえクリアできていればインストール方法自体は非常にシンプルで、GitHubのリリースページからmsixbundleファイルをダウンロードしてやるだけです。

簡単なPowerShell関数を作りましたので以下のスクリプトを実行すれば最新のWindows Terminalをサクッとインストールできます。

Install-LatestWindowsTerminal.ps1
#
# ※ブログ初回公開時と内容が異なります (2023年10月アップデート済み)
#
function Install-LatestWindowsTerminal ([switch]$SkipInstallVCLibs) {
    # Check OS version
    $buildVersion = [Version](Get-CimInstance -ClassName 'Win32_OperatingSystem' -Property Version | Select-Object -ExpandProperty Version)
    $isWin11 = if ($buildVersion -ge ([Version]"10.0.22000.0") ) { $true } else { $false }

    # Get the latest release information
    $latest = Invoke-RestMethod -Uri 'https://api.github.com/repos/microsoft/terminal/releases/latest'
    $installerUrl = $latest.assets | Where-Object { $_.browser_download_url -like '*.msixbundle_Windows10_PreinstallKit.zip' } | Select-Object -ExpandProperty browser_download_url -First 1
    if ([string]::IsNullOrEmpty($installerUrl)) {
        Write-Error 'Failed to get the installer url'
        return
    }

    # For Windows 10, Need to install VCLibs
    if ((-not $isWin11) -and (-not $SkipInstallVCLibs)) {
        $vcLibsUrl = 'https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx'
        Write-Host -ForegroundColor Green "Download $vcLibsUrl"
        Add-AppxPackage -Path $vcLibsUrl
    }

    # Download zip and expand items
    Write-Host -ForegroundColor Green "Download $installerUrl"
    $zipPath = Join-Path -Path ([IO.Path]::GetTempPath()) ($installerUrl -split '/')[-1]
    try {
        $client = [System.Net.WebClient]::new() 
        $client.DownloadFile($installerUrl, $zipPath)
    } finally {
        $client.Dispose()
    }

    Add-Type -AssemblyName System.IO.Compression.FileSystem
    $xamlUIPath = ''
    $bundlePath = ''
    try {
        $archive = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
        # Extract Microsoft.UI.Xaml appx 
        $archName = switch ($env:PROCESSOR_ARCHITECTURE) {
            'x86' { 'x86' }
            'AMD64' { 'x64' }
            'ARM64' { 'arm64' }
            Default { 'x64' }
        }
        $item = $archive.Entries | Where-Object { $_.FullName -like "Microsoft.UI.Xaml*_${archName}*.appx" } | Select-Object -First 1
        if ($item) {
            $xamlUIPath = Join-Path -Path ([IO.Path]::GetTempPath()) ($item.Name)
            Write-Host -ForegroundColor Green "Extract $($item.Name) to $xamlUIPath"
            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($item, $xamlUIPath)
        }
        # Extract msixbundle
        $item = $archive.Entries | Where-Object { $_.FullName -like '*.msixbundle' } | Select-Object -First 1
        if ($item) {
            $bundlePath = Join-Path -Path ([IO.Path]::GetTempPath()) ($item.Name)
            Write-Host -ForegroundColor Green "Extract $($item.Name) to $bundlePath"
            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($item, $bundlePath)
        }
    } finally {
        if ($archive) {
            $archive.Dispose()
        }
    }

    # Install Microsoft.UI.Xaml appx
    if (-not $isWin11) {
        Write-Host -ForegroundColor Green "Install $xamlUIPath"
        Add-AppxPackage -Path $xamlUIPath
    }

    # Install MSIX bundle
    Write-Host -ForegroundColor Green "Install $bundlePath"
    Add-AppxPackage -Path $bundlePath

    # Remove files
    ($bundlePath, $xamlUIPath, $zipPath) | ForEach-Object {
        if (Test-Path -LiteralPath $_) {
            Write-Host -ForegroundColor Green "Remove $_"
            Remove-Item -LiteralPath $_
        }
    }
    Write-Host -ForegroundColor Green "Installation complete!"
}
Install-LatestWindowsTerminal

image

これでよしなにWindows TerminalがインストールされWindows Server 2022で利用可能になります。

image

おまけ : Windows Package Manager Client (winget)をインストールする

Windows Terminalと同様の理屈でWindows Package Manager Client (winget)もインストール可能です。

wingetの場合はアプリケーションのmsixbunldeファイル以外にVCライブラリのインストールが必要となる点、ライセンスファイルも同時にインストールする必要があるためAdd-AppxProvisionedPackageを使う必要がある点が異なります。

Install-LatestWinGet.ps1
#
# ※ブログ初回公開時と内容が異なります (2024年6月アップデート済み)
#
function Install-LatestWinGet ([switch]$SkipInstallVCLibs) {
    # Install prerequisites
    if (-not $SkipInstallVCLibs) {
        $vcLibsUrl = 'https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx'
        Write-Host -ForegroundColor Green "Download $vcLibsUrl"
        Add-AppxPackage -Path $vcLibsUrl
    }

    # Find the latest assets url
    $latest = Invoke-RestMethod -Uri 'https://api.github.com/repos/microsoft/winget-cli/releases/latest'
    $msixUrl = $latest.assets | Where-Object { $_.browser_download_url -like '*.msixbundle' } | Select-Object -ExpandProperty browser_download_url
    $msixPath = Join-Path -Path ([IO.Path]::GetTempPath()) ($msixUrl -split '/')[-1]
    $licenseUrl = $latest.assets | Where-Object { $_.browser_download_url -like '*License1.xml' } | Select-Object -ExpandProperty browser_download_url
    $licensePath = Join-Path -Path ([IO.Path]::GetTempPath()) ($licenseUrl -split '/')[-1]

    # Download assets
    ( @{Url = $msixUrl ; LocalPath = $msixPath }, @{Url = $licenseUrl ; LocalPath = $licensePath } ) | ForEach-Object {
        Write-Host -ForegroundColor Green "Download $($_.Url)"
        try {
            $client = [System.Net.WebClient]::new() 
            $client.DownloadFile($_.Url, $_.LocalPath)
        } finally {
            $client.Dispose()
        }
    }

    # Install MSIX to provisioned package
    Write-Host -ForegroundColor Green "Install $msixPath"
    Write-Host -ForegroundColor Green "  : License $licensePath"
    Add-AppxProvisionedPackage -Online -PackagePath $msixPath -LicensePath $licensePath
    # Install Microsoft.UI.Xaml 2.8.6 (need fixed version)
    Write-Host -ForegroundColor Green "Install Microsoft.UI.Xaml 2.8.6"
    $archName = switch ($env:PROCESSOR_ARCHITECTURE) {
        'x86' { 'x86' }
        'AMD64' { 'x64' }
        'ARM64' { 'arm64' }
        Default { 'x64' }
    }
    Add-AppxPackage -Path "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.${archName}.appx"
    # Register MSIX 
    Write-Host -ForegroundColor Green "Registter Microsoft.DesktopAppInstaller"
    Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe

    # Remove assets
    ($msixPath, $licensePath) | ForEach-Object {
        if (Test-Path -LiteralPath $_) {
            Write-Host -ForegroundColor Green "Remove $_"
            Remove-Item -LiteralPath $_
        }
    }
    Write-Host -ForegroundColor Green "Installation complete!"
}
Install-LatestWinGet

image

これでwingetを使っていろいろなソフトウェアをインストールできます。
なお、wingetインストール後はログインし直してください。

image

(上図はVS Codeをインストールしてみた図)

Gist

一応私のGistにもコードを載せておきます。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.